// Traffic logger for detailed connection logging

use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use std::sync::Arc;
use tokio::sync::RwLock;
use tracing::info;

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TrafficLog {
    pub timestamp: DateTime<Utc>,
    pub user_id: String,
    pub remote_addr: String,
    pub action: TrafficAction,
    pub bytes_tx: u64,
    pub bytes_rx: u64,
    pub duration_ms: u64,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum TrafficAction {
    Connect,
    Disconnect,
    TcpRequest { target: String },
    UdpSession { target: String },
}

pub struct TrafficLogger {
    logs: Arc<RwLock<Vec<TrafficLog>>>,
    max_logs: usize,
}

impl TrafficLogger {
    pub fn new(max_logs: usize) -> Self {
        Self {
            logs: Arc::new(RwLock::new(Vec::new())),
            max_logs,
        }
    }

    pub async fn log(&self, log: TrafficLog) {
        info!(
            "Traffic: user={}, action={:?}, tx={}, rx={}",
            log.user_id, log.action, log.bytes_tx, log.bytes_rx
        );

        let mut logs = self.logs.write().await;
        logs.push(log);

        // Keep only recent logs
        if logs.len() > self.max_logs {
            logs.drain(0..logs.len() - self.max_logs);
        }
    }

    pub async fn get_logs(&self, limit: usize) -> Vec<TrafficLog> {
        let logs = self.logs.read().await;
        logs.iter()
            .rev()
            .take(limit)
            .cloned()
            .collect()
    }

    pub async fn get_user_logs(&self, user_id: &str, limit: usize) -> Vec<TrafficLog> {
        let logs = self.logs.read().await;
        logs.iter()
            .rev()
            .filter(|log| log.user_id == user_id)
            .take(limit)
            .cloned()
            .collect()
    }

    pub async fn clear_logs(&self) {
        self.logs.write().await.clear();
    }
}

impl Default for TrafficLogger {
    fn default() -> Self {
        Self::new(10000)
    }
}
